# -*- coding: utf-8 -*- 
from Cheetah.Template import Template
import sys
import os
import shutil
import json
import gettext
import hashlib
import time
import zoo
try:
	from manage_users.manage_users import *
except:
	from manage_users import manage_users

def parseDb(db):
	dbstr=""
	for i in db:
		if i!="schema":
			dbstr+=" "+i+"="+db[i]
	#print >> sys.stderr,dbstr
	return dbstr

def getCon(conf):
	if conf["main"].has_key(conf["main"]["dbuser"]) and conf["main"]["dbuser"]=="dblink":
		print >> sys.stderr,"DB IS SQLITE"
		con=manage_users(conf["main"][conf["main"]["dbuser"]])
	else:
		if conf.has_key(conf["main"]["dbuser"]):
			#print >> sys.stderr,"DB IS POSTGRESQL"
			con=manage_users(parseDb(conf[conf["main"]["dbuser"]]))
	con.connect(conf)
	return con

def getPrefix(conf):
	if conf.has_key(conf["main"]["dbuser"]) and conf[conf["main"]["dbuser"]].has_key("schema"):
		prefix=conf[conf["main"]["dbuser"]]["schema"]+"."
	else:
		prefix=""
	return prefix

def sendMail(conf,typ,dest,login,passwd):
	import smtplib
	from email.mime.text import MIMEText
	f0=open(conf["smtp"][typ+"_body"])
	msgTxt=zoo._(f0.read()).replace("[passwd]",passwd).replace("[login]",login).encode('utf-8')
	msg=MIMEText(msgTxt,_charset='utf-8')
	f1=open(conf["smtp"][typ+"_subject"])
	msg['Subject'] = zoo._(f1.read()).replace('\n','').encode("utf-8")
	if conf["smtp"].has_key('ufrom'):
		msg["From"]="<"+conf["smtp"]["from"]+"> "+zoo._(conf["smtp"]["ufrom"])
	else:
		msg["From"]=conf["smtp"]["from"]
	msg["To"]=dest
	serv=smtplib.SMTP(conf["smtp"]["host"],conf["smtp"]["port"])
	if conf["smtp"].has_key("login"):
		serv.login(conf["smtp"]["login"],conf["smtp"]["passwd"])
	serv.sendmail(conf["smtp"]["from"], [dest], msg.as_string())
	
	
def getLostPassword(conf,inputs,outputs):
	import random,string
	if not(conf.has_key("smtp")):
		conf["lenv"]["message"]=zoo._("SMTP is not properly configured on your instance, please follow instructions from the official documentation.")
		return zoo.SERVICE_FAILED
	passwd = ''.join(random.choice(string.ascii_lowercase + string.digits) for x in range(8))
	con=getCon(conf)
	prefix=getPrefix(conf)
	con.connect()
	conn = con.conn
	cur=conn.cursor()
	cur.execute('SELECT login,mail from '+prefix+'users where login=\''+inputs["login"]["value"]+'\' or mail=\''+inputs["login"]["value"]+'\'')
	a=cur.fetchall()
	if len(a)>0:
		try:
			passwd = ''.join(random.choice(string.ascii_lowercase + string.digits) for x in range(8))
			h = hashlib.new('ripemd160')
			h.update(passwd)
			cur.execute('update '+prefix+'users set passwd=\''+h.hexdigest()+'\' where login=\''+a[0][0]+'\'')
			conn.commit()
			sendMail(conf,"recovery",a[0][1],a[0][0],passwd)
		except Exception,e:
			conf["lenv"]["message"]=zoo._("Unable to send the mail containing your new password: ")+str(e)
			return zoo.SERVICE_FAILED
	else:
		conf["lenv"]["message"]=zoo._("Nor login nor email address correspond to the value provided")
		return zoo.SERVICE_FAILED
	outputs["Result"]["value"]=zoo._("You will receive an email containing your new password")
	return zoo.SERVICE_SUCCEEDED

def saveUserPreferences(conf,inputs,outputs):
	con=getCon(conf)
	con.connect()
	conn = con.conn
	prefix=getPrefix(conf)
	j=0
	sqlStr=""
	if inputs["fields"].has_key("length"):
		for i in inputs["fields"]["value"]:
			if i!="login" and inputs["values"]["value"][j]!="NULL":
				if sqlStr!="":
					sqlStr+=", "
				if i=="passwd":
					h = hashlib.new('ripemd160')
					h.update(inputs["values"]["value"][j])
					sqlStr+=i+"='"+h.hexdigest()+"'"
				else:
					sqlStr+=i+"='"+inputs["values"]["value"][j]+"'"
			j+=1
	else:
		sqlStr+=inputs["fields"]["value"]+"='"+inputs["values"]["value"]+"'"		
		#print >> sys.stderr,sqlStr
	cur=conn.cursor()
	try:
		sql="UPDATE "+prefix+"users set "+sqlStr+" where login='"+conf["senv"]["login"]+"'"
		#print >> sys.stderr,sql
		cur.execute(sql)
		conn.commit()
	except Exception,e:
		conf["lenv"]["message"]=zoo._("Unable to update user preferences: ")+str(e)
		return zoo.SERVICE_FAILED
	outputs["Result"]["value"]=zoo._("User preferences saved.")
	return zoo.SERVICE_SUCCEEDED

def registerUser(conf,inputs,outputs):
	con=getCon(conf)
	prefix=getPrefix(conf)
	con.connect()
	conn = con.conn
	j=0
	fieldsStr=""
	valuesStr=""
	login=""
	mail=""
	for i in inputs["fields"]["value"]:
		if inputs["values"]["value"][j]!="NULL" and inputs["fields"]["value"][j]!="s_group_id":
			if fieldsStr!="":
				fieldsStr+=", "
				valuesStr+=", "
			if i=="passwd":
				h = hashlib.new('ripemd160')
				h.update(inputs["values"]["value"][j])
				valuesStr+="'"+h.hexdigest()+"'"
				fieldsStr+=i
			else:
				if i=="login":
					login=inputs["values"]["value"][j]
				else:
					if i=="mail":
						mail=inputs["values"]["value"][j]
				valuesStr+="'"+inputs["values"]["value"][j]+"'"
				fieldsStr+=i
		j+=1
	cur=conn.cursor()
	try:
		sql="INSERT INTO "+prefix+"users ("+fieldsStr+") VALUES("+valuesStr+")"
		#print >> sys.stderr,sql
		cur.execute(sql)
		sql="INSERT INTO "+prefix+"user_group (id_group,id_user) VALUES("+inputs["values"]["value"][inputs["fields"]["value"].index("s_group_id")]+",(select last_value from velo.velo_users_idseq))"
		cur.execute(sql)
		if conf.has_key("smtp"):
			sendMail(conf,"register",mail,login,"XXX")
		conn.commit()
	except Exception,e:
		conf["lenv"]["message"]=zoo._("Unable to register the user: ")+str(e)
		return zoo.SERVICE_FAILED
	outputs["Result"]["value"]=zoo._("User have been successfully registered.")
	return zoo.SERVICE_SUCCEEDED

def logOut(conf,inputs,outputs):
	#print >> sys.stderr,conf["senv"]
	if conf.keys().count("senv")>0 and conf["senv"].keys().count("loggedin")>0 and conf["senv"]["loggedin"]=="true":
		outputs["Result"]["value"]=zoo._("User disconnected")
		conf["senv"]["loggedin"]="false"
		conf["lenv"]["cookie"]=conf["main"]["cookiePrefix"]+"=deleted; expires="+time.strftime("%a, %d-%b-%Y %H:%M:%S GMT",time.gmtime())+"; path=/"
		return zoo.SERVICE_SUCCEEDED
	else:
		conf["lenv"]["message"]=zoo._("User not authenticated")
		return zoo.SERVICE_FAILED
	conf["lenv"]["message"]=zoo._("User not authenticated")
	return zoo.SERVICE_FAILED

def getGroup(conf,c,login):
	try:
		prefix=getPrefix(conf)
		req="select groups.name from "+prefix+"users,"+prefix+"user_group,"+prefix+"groups WHERE "+prefix+"users.id=id_user AND "+prefix+"groups.id=id_group AND login='"+login+"'"
		c.execute(req)
		a=c.fetchall()
		res=""
		for i in range(0,len(a)):
			for j in range(0,len(a[i])):
				if res!="":
					res+=","
				res+=a[i][j]
		return res
	except Exception as e:
		#print >> sys.stderr,zoo._("Error when processing SQL query: ")+str(e)
		return None

def logIn(conf,inputs,outputs):
	if conf.keys().count("senv") > 0 and conf["senv"] and conf["senv"]["loggedin"]=="true":
		conf["lenv"]["message"]=zoo._("No need to authenticate")
		return zoo.SERVICE_FAILED
	con=getCon(conf)
	con.conf=conf
	prefix=getPrefix(conf)
	con.connect(conf)
	try:
		conn = con.conn
	except:
		conf["lenv"]["message"]=zoo._("Unable to connect to the User Database.")
		return zoo.SERVICE_FAILED
	h = hashlib.new('ripemd160')
	h.update(inputs['password']['value'])
	h.hexdigest()
	c = conn.cursor()
	try:
		req=" SELECT users.*,(select name from "+prefix+"groups where id=id_group) as gname FROM "+prefix+"users,"+prefix+"user_group,"+prefix+"groups WHERE "+prefix+"users.id=id_user AND "+prefix+"groups.id=id_group AND adm=1 AND login='"+inputs['login']['value']+"' AND passwd='"+h.hexdigest()+"' "
		c.execute(req)
	except Exception as e:
		conf["lenv"]["message"]=zoo._("Error when processing SQL query: ")+str(e)
		return zoo.SERVICE_FAILED
	a=c.fetchall()

	if len(a)>0:
		conf["lenv"]["cookie"]=conf["main"]["cookiePrefix"]+"=ows_"+str(time.time()).split(".")[0]+"; path=/"

		
		conf["senv"]={}
		conf["senv"][conf["main"]["cookiePrefix"]]="ows_"+str(time.time()).split(".")[0]
		
		# Set all the Session environment variables using the users 
		# table content.
		#print >> sys.stderr,con.desc
		c.execute(con.desc)
		desc=c.fetchall()
		for i in desc:
			if isinstance(a[0][i[0]],int):
				conf["senv"][i[1]]=str(a[0][i[0]])
			else:
				if a[0][i[0]] is not None:
					try:
						conf["senv"][i[1]]=a[0][i[0]].encode('utf-8')
					except:
						conf["senv"][i[1]]=a[0][i[0]]
				else:
					conf["senv"][i[1]]=str(a[0][i[0]])

		conf["senv"]["group"]=getGroup(conf,c,inputs['login']['value'])
		conf["senv"]["loggedin"]="true"
		conf["senv"]["isAdmin"]="true"
		#print >> sys.stderr,conf["senv"]

		if conf["main"].has_key("isTrial") and conf["main"]["isTrial"]=="true":
			conf["senv"]["isTrial"]="true"
		else:
			conf["senv"]["isTrial"]="false"


		outputs["Result"]["value"]=zoo._("User ")+conf["senv"]["login"]+zoo._(" authenticated")
		sql=" UPDATE "+prefix+"users set last_con="+con.now+" WHERE login='"+inputs['login']['value']+"' "
		c.execute(sql)
		conn.commit()
		return zoo.SERVICE_SUCCEEDED
	else:
		conf["lenv"]["message"]=zoo._("Unable to connect with the provided login and password")
		return zoo.SERVICE_FAILED

	sys.path+=[conf["main"]["templatesPath"]]
	conf["lenv"]["message"]=zoo._("Should never occur")
	return zoo.SERVICE_FAILED

